package com.jinzhi.jzdoor.certificate.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.configconsts.wxconsts.LinkConfiggure;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.utils.*;
import com.jinzhi.common.vo.WxPayConfig;
import com.jinzhi.common.vo.WxPayVo;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserRoleService;
import com.jinzhi.sys.service.UserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ChainBase;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.jinzhi.api.util.TokenTag.TOKEN_TAG;


@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/userInfo")
public class InfoUserController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private OrganizationNewsService organizationNewsService;
    @Autowired
    private ExpertsService expertsService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private StuSignUpService stuSignUpService;
    @Autowired
    private CertificateNewsService certificateNewsService;
    @Autowired
    private CertificationBatchService certificationBatchService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ChainBase wxPaySignUpChain;
    @Autowired
    private WxPayConfig wxPayConfig;

    private static BigDecimal bigDecimal;

    static {
        bigDecimal = new BigDecimal(100);
    }

    /**
     * 证书门户端-考生报名微信支付接口（扫码支付）
     *
     * @Description: 证书门户端微信扫码支付 ，参数：wxpayVO虚拟实体（接收参数total_fee-支付金额，body-支付内容，trade_type-支付类型），考生报名id
     * @Param: [wxPayVo, stuSignUpId]
     * @return: com.jinzhi.common.utils.ApiResult<?>
     * @Author: kl
     * @Date: 2020-03-16
     */
    @PostMapping("/wxPay")
    @Log("证书门户端-考生报名微信支付接口（扫码支付）")
    @ApiOperation(value = "证书门户端-考生报名微信支付接口（扫码支付）", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @RequiresAuthentication
    @ApiImplicitParams({@ApiImplicitParam(name = TOKEN_TAG, value = TOKEN_TAG, paramType = "header")})
    @Transactional
    public ApiResult<?> wxPay(@RequestHeader(value = TOKEN_TAG, required = false) String token,@Validated WxPayVo wxPayVo, String stuSignUpId) {
         //1.根据token获取用户登录数据
        UserDO user = this.getClientUser(token);
        if (null == user) {
            return ApiResult.invalid();
        }

        ApiResult apiResult = new ApiResult();
        try {
            //判断考生报名id是否为空
            if (null == stuSignUpId || stuSignUpId == "undefined") {
                return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:stuSignUpId");
            }

            String cerName = "考生线上报名(门户端）";
            Double amouts = -1.0;
            StuSignUpDO stuSignUpDO = stuSignUpService.selectById(Long.parseLong(stuSignUpId));
            if(stuSignUpDO == null){
                return ApiResult.build(ApiEnumError.dateGetError.getCode(),ApiEnumError.dateGetError.getMsg());
            }else{
                CertificationBatchDO certificationBatchDO = certificationBatchService.selectById(stuSignUpDO.getCbatchId());
                if(certificationBatchDO == null){
                    return ApiResult.build(ApiEnumError.dateGetError.getCode(),ApiEnumError.dateGetError.getMsg());
                }else{
                    cerName = certificationBatchDO.getName() + "--线上报名(门户端）";
                    CertificateNewsDO certificateNewsDO = certificateNewsService.selectById(certificationBatchDO.getNewsId());
                    if(certificateNewsDO == null){
                        return ApiResult.build(ApiEnumError.dateGetError.getCode(),ApiEnumError.dateGetError.getMsg());
                    }else{
                        amouts = certificateNewsDO.getExamFee();
                    }
                }
            }

            if(amouts == -1.0){
                return ApiResult.build(ApiEnumError.dateGetError.getCode(),ApiEnumError.dateGetError.getMsg());
            }

            OrderDO orderDOs = orderService.findOneByKv("object_id",Long.parseLong(stuSignUpId));
            if(orderDOs == null){
                //新增订单信息 --2020-05-18 kl
                OrderDO orderDO = new OrderDO();
                orderDO.setType(1);//订单类型为报名
                orderDO.setUserId(user.getId());//用户id
                orderDO.setObjectId(Long.parseLong(stuSignUpId));//考生id
                orderDO.setOrderAmount(amouts);//订单金额
                orderDO.setName(cerName);//订单名称
                orderDO.setState(1);//默认未付款
                boolean bbc = orderService.insert(orderDO);
                if(!bbc){
                    return ApiResult.build(ApiEnumError.ORDERSAVEERR.getCode(),ApiEnumError.ORDERSAVEERR.getMsg());
                }
            }

            //通过uuid生成商户id
            String out_trade_no = UUID.randomUUID().toString().replace("-", "");
            //生成32为随机数
            String randomStringBy = StringUtil.getRandomStringByLength(32);

            wxPayVo.setAppid(wxPayConfig.getAppId());//appid（微信公众号）
            wxPayVo.setMch_id(wxPayConfig.getMerNo());//商户id
            wxPayVo.setNotify_url(wxPayConfig.getSignUpNotify());//回调地址
            wxPayVo.setSpbill_create_ip(wxPayConfig.getIp());//ip地址
            wxPayVo.setOut_trade_no(out_trade_no);
            wxPayVo.setNonce_str(randomStringBy);
            wxPayVo.setTotal_fee(new BigDecimal(amouts.toString()).multiply(bigDecimal).setScale(0).toString());//支付金额
            wxPayVo.setLabel(WxPayLabelEnum.stupOrder.getTag());
            wxPayVo.setType(AppEnum.certificates.getTag());

            log.info("商户订单号:" + out_trade_no);

            //保存用户id至缓存，为后面回调提供
            EhCacheUtil.put(out_trade_no + ":stuSignUpId", Long.parseLong(stuSignUpId));

            //创建上下文
            Context context = new ContextBase();

            //微信支付对象
            context.put(LinkConfiggure.WX_PAY_VO, wxPayVo);
            //固定返回对象
            context.put(LinkConfiggure.API_RESULT, apiResult);
            //订单id(考生报名id）
            context.put("stuSignUpId", Long.parseLong(stuSignUpId));
            //用户id
            context.put("user_id",  user.getId());
            //商户订单号
            context.put("out_trade_no", out_trade_no);

            //开始链路
            wxPaySignUpChain.execute(context);
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new RuntimeException(e);
        }
        Map map = new HashMap();
        map.put("type", "wx");
        map.put("wx", apiResult);
        return ApiResult.success(map);
    }


    /**
     * 证书门户端-查询报名缴费状态
     *
     * @Description: 根据考生报名id查信息状态，参数：考生报名id
     * @Param: [stuSignUpId]
     * @return: com.jinzhi.common.utils.ApiResult<?>
     * @Author: kl
     * @Date: 2020-03-16
     */
    @GetMapping("/selSignUpState")
    @Log("证书门户端-查询报名缴费状态")
    @ApiOperation(value = "证书门户端-查询报名缴费状态", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @RequiresAuthentication
    @Transactional
    public ApiResult<?> selSignUpState(String stuSignUpId) {
        if(stuSignUpId == null){
            return ApiResult.fail("参数缺失");
        }
        StuSignUpDO stuSignUpDO = stuSignUpService.selectById(stuSignUpId);
        if(stuSignUpDO != null){
            return ApiResult.success(stuSignUpDO.getState());
        }

        return ApiResult.fail();
    }
}
